<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #oCanvas {
            border: 1px solid #000;
        }
    
    </style>
</head>

<body>
    <canvas id="oCanvas" width="500" height="400"></canvas>
    <script type="notjs" id="vertex">
         /*
          顶点着色器 
         */
        attribute vec4 a_position;
        //uniform vec4 u_Translate;
       // uniform float Tx, Ty, Tz;
        // uniform float u_cosb,u_sinb;
        // uniform mat4 u_TranslateMetrix;
        // uniform mat4 u_rotateMetrix; 
        uniform mat4 u_matrix;
        void main() {
            //  rotateMatrix` * translateMatrix`  = (translateMatrix * rotateMatrix)`
            // u_rotateMetrix`  *    u_TranslateMetrix`   !=   u_TranslateMetrix * u_TranslateMetrix
            // u_matrix  = u_rotateMetrix * u_TranslateMetrix
            gl_Position = u_matrix * a_position;
        }
    </script>
    <script type="notjs" id="fragment">
        /*
            片元着色器 ： 绘制颜色或者纹理的 —— 水彩的作用
        */
        precision mediump float;

        void main() {
            gl_FragColor = vec4(0, 0, 0, 1);
        }

    </script>
    <script>
        var canvas = document.getElementById('oCanvas');
        var gl = canvas.getContext('webgl');
        if (!gl) {
            console.log('浏览器不兼容webgl');
        }

        var vertex = document.getElementById('vertex').innerText;
        var fragment = document.getElementById('fragment').innerText;

        // 顶点着色器 gl.VERTEX_SHADER   片元着色器 gl.FRAGMENT_SHADER;
        function createShader(gl, type, source) {
            var shader = gl.createShader(type);
            //  添加数据源
            gl.shaderSource(shader, source);
            gl.compileShader(shader);

            var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
            if (success) {
                return shader;
            }
            console.log(gl.getShaderInfoLog(shader));
        }

        var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertex);
        var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragment);

        function createProgram(gl, vertexShader, fragmentShader) {
            var program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            var success = gl.getProgramParameter(program, gl.LINK_STATUS);
            if (success) {
                return program;
            }
            console.log(gl.getProgramInfoLog(program));
        }
        var program = createProgram(gl, vertexShader, fragmentShader);
        gl.useProgram(program);

        gl.clearColor(0, 0, 0, 0.5);
        gl.clear(gl.COLOR_BUFFER_BIT);
        // 获取a_position 存储位置
        var a_position = gl.getAttribLocation(program, 'a_position');
        var u_rotateMetrix = gl.getUniformLocation(program, 'u_rotateMetrix');
        var u_TranslateMetrix = gl.getUniformLocation(program, "u_TranslateMetrix");
        var u_matrix = gl.getUniformLocation(program, "u_matrix");
        var Tx = 0.5, Ty = 0, Tz = 0;

        var  m3 = {
            translate: function (Tx, Ty, Tz) {
                return [
                    1.0, 0, 0, 0,
                    0, 1.0, 0, 0,
                    0, 0, 1.0, 0,
                    Tx, Ty, Tz, 1.0
                ];
            },
            rotatez: function (deg) {
                var sinb = Math.sin(deg * Math.PI / 180).toFixed(2);
                var cosb = Math.cos(deg * Math.PI / 180).toFixed(2);
                return [
                    cosb, sinb, 0, 0,
                    -sinb, cosb, 0, 0,
                    0, 0, 1, 0,
                    0, 0, 0, 1
                ];
            },
            scale: function (Sx, Sy, Sz) {
                return [
                    Sx, 0, 0, 0,
                    0, Sy, 0, 0,
                    0, 0, Sz, 0,
                    0, 0, 0, 1,
                ];
            },
            muliply: function (a, b) {
                var a00 = a[0 * 4 + 0];
                var a01 = a[0 * 4 + 1];
                var a02 = a[0 * 4 + 2];
                var a03 = a[0 * 4 + 3];
                var a10 = a[1 * 4 + 0];
                var a11 = a[1 * 4 + 1];
                var a12 = a[1 * 4 + 2];
                var a13 = a[1 * 4 + 3];
                var a20 = a[2 * 4 + 0];
                var a21 = a[2 * 4 + 1];
                var a22 = a[2 * 4 + 2];
                var a23 = a[2 * 4 + 3];
                var a30 = a[3 * 4 + 0];
                var a31 = a[3 * 4 + 1];
                var a32 = a[3 * 4 + 2];
                var a33 = a[3 * 4 + 3];
                var b00 = b[0 * 4 + 0];
                var b01 = b[0 * 4 + 1];
                var b02 = b[0 * 4 + 2];
                var b03 = b[0 * 4 + 3];
                var b10 = b[1 * 4 + 0];
                var b11 = b[1 * 4 + 1];
                var b12 = b[1 * 4 + 2];
                var b13 = b[1 * 4 + 3];
                var b20 = b[2 * 4 + 0];
                var b21 = b[2 * 4 + 1];
                var b22 = b[2 * 4 + 2];
                var b23 = b[2 * 4 + 3];
                var b30 = b[3 * 4 + 0];
                var b31 = b[3 * 4 + 1];
                var b32 = b[3 * 4 + 2];
                var b33 = b[3 * 4 + 3];



                return  [
                    a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30,
                    a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31,
                    a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32,
                    a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33,

                    a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30,
                    a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31,
                    a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32,
                    a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33,

                    a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30,
                    a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31,
                    a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32,
                    a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33,

                    a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30,
                    a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31,
                    a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32,
                    a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33,
                ]
            }
        }


        var translateMatrix = m3.translate(0.5, 0, 0);
        // gl.uniformMatrix4fv(u_TranslateMetrix, false, new Float32Array(m3.translate(0.5, 0, 0)));
        // 拿到顶点着色器中  矩阵转置变成  rotateMatrix` * translateMatrix`

        //  在js里面如果要实现 rotateMatrix` * translateMatrix` = （translateMatrix * rotateMartix）`
        var rotateDeg = 90;
        function rotate() {
            // rotateDeg += 1;
            draw(rotateDeg);
            requestAnimationFrame(rotate);
        }
        function draw (deg) {
            rotateDeg = deg ? deg : rotateDeg;
            var sinb = Math.sin(rotateDeg * Math.PI / 180).toFixed(2);
            var cosb = Math.cos(rotateDeg * Math.PI / 180).toFixed(2);
            var rotateMatrix = m3.rotatez(rotateDeg);
            var scaleMatrix = m3.scale(0.5, 1, 1);
            // translateMatrix * rotateMatrix
            // 在js里  先平移再旋转   谁先谁在前
            // 在顶点着色器里   县平移在旋转   谁先谁在后
            var matrix = m3.muliply(translateMatrix, rotateMatrix);
            matrix = m3.muliply(matrix, scaleMatrix)
            gl.uniformMatrix4fv(u_matrix, false, new Float32Array(matrix));
            var positionBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
                0.0, 0.0, 0.0,
                0.5, 0.5, 0.0,
                0.0, 0.5, 0.0,
                // 0.0, 0.0, 0.0,
                // 0.5, 0.0, 0.0,
                // 0.5, 0.5, 0.0,
            ]), gl.STATIC_DRAW);

            gl.vertexAttribPointer(a_position, 3, gl.FLOAT, true, 0, 0);
            gl.enableVertexAttribArray(a_position);
            gl.drawArrays(gl.TRIANGLES, 0, 3);

        }
       
 
    </script>
</body>

</html>
